SQlite源码分析

页面类型

Sqlite中的页面类型包括:
       叶子页面(leaf):存储数据;
       内部页面(internal): 包含查询时的导航信息;
       溢出页面(overflow);
       空闲页面(free);
       (1). file header
文件以1号页面开始,它包括100个字节的文件头。
Header string(头字符串):16个字节,"SQLite format 3."
Page size(页面大小):1024
File format(文件格式):在当前的版本都为1。
Reserved space(保留空间):1个字节,SQLite在每个页面的末尾都会保留一定的空间,留作它用,默认为0。
Embedded payload:max embedded payload fraction(偏移21)的值限定了B树内节点(页面)中一个元组(记录,单元)最多能够使用的空间。255意味着100%,默认值为0x40,即64(25%),这保证了一个结点(页面)至少有4个单元。如果一个单元的负载(payload,即数据量)超过最大值,则溢出的数据保存到溢出的页面,一旦SQLite分配了一个溢出页面,它会尽可能多的移动数据到溢出页面,下限为min embedded payload fraction value(偏移为22),默认的值为32,即12.5% 。
File change counter(文件修改计数):通常被事务使用,它由事务增加其值。该值的主要目的是数据库改变时,pager避免对缓存进行刷盘。
       Freelist(空闲页面链表):在文件头偏移32的4个字节记录着空闲页面链的第一个页面,偏移36处的4个字节为空闲页面的数量。
       空闲页面分为两种页面:trunk pages(主页面)和leaf pages(叶子页面)。文件头的指针指向空闲链表的第一个trunk page,每个trunk page指向多个叶子页面。
Trunk page的格式如下,从页面的起始处开始:
       4个字节,指向下一个trunk page的页面号;
       4个字节,该页面的叶子页面指针的数量;
       指向叶子页面的页面号,每项4个字节。
       Meta variables(元数据变量):
从偏移为40开始,为15个4字节的元数据变量,这些元数据主要与B树和VM有关。
       (2). 读取file
       程序调用API sqlite3_open打开数据库文件时,SQLite就会读取文件头进行数据库的初始化。
       数据库文件页的可复写条件:
       ①在事务开始的时候,页面的源文件就应该被写入回滚日志并同步。
       ②pager在事务开始的时候是freelist的叶子页面。
       ③在事务开始的时候,页码要大于数据库文件中的最大页。
       当然数据库文件页也有一些不可复写的,除了①某个页面同其他页面在同一个扇区。②原子页的写优化是可行的,整个事务除了事务序列号的更新,都由一个单一的页变化组成。